import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Semaphore;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;


public class MultiThreadingServer extends JInternalFrame implements Runnable{

	private ArrayList<String> groups;
	private Map<String, Number> groupsWithNetworkPorperties;
	private JTextArea  statusArea;	
	private DatagramSocket serverSocket = null; 
	private InetAddress myIpAddress = null;
	private int myPort;
	private boolean isRunning = true;
	private  JButton clearButton; 
	public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
	private int numberOfBytesTransfered = 0;
	private Map<String, String> trafficByGroup;
	private Semaphore mutex;
	private GroupDataInterface groupData;
	
	public MultiThreadingServer(int port, Semaphore mutex, GroupDataInterface groupData) { 	
		
		super( "Status Area",
                true, //resizable
                true, //closable
                true, //maximizable
                true  //iconifiable
              );		
		this.groupData = groupData;
		this.mutex = mutex;
		this.setupGUI();
		this.printStatusMsg("GroupTalk Server v0.010, 27.05.2011\n");		
		this.printStatusMsg("Init Server...\n");
		this.groups = new ArrayList<String>(); 
		
		try {
			this.myPort = port;
			this.serverSocket = new DatagramSocket(port);
			this.myIpAddress = InetAddress.getLocalHost();
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.exit(1);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			this.printStatusMsg("Server is running on "+this.serverSocket.getLocalAddress().getLocalHost().toString()+":"+this.myPort+"\n");
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		new Thread(this).start();
		
	}	 
	
	public void run() {
		 
	
		 while(isRunning) {			 
			
			byte[] buffer = new byte[524];			
			DatagramPacket packet = new DatagramPacket(buffer, buffer.length);		
			 
			try {
				this.serverSocket.receive(packet);
				RtpPacket rtpPacket = new RtpPacket(packet.getData(), packet.getData().length);
				
				if(rtpPacket.getP() == 1 && rtpPacket.getX() == 1) {
					
					String data = new String(rtpPacket.getPayload());
					String[] groupInformation = data.split(",");
					
					System.out.println("MESG: "+groupInformation[0]);
					
					
					if(groupInformation[0].equals("CNG")) {
						this.printStatusMsg("Create Group Request from: "+packet.getAddress().getHostAddress()+"\n");
					}
					
					else if(groupInformation[0].equals("JG")) {
						this.printStatusMsg("Join Group Request from: "+packet.getAddress().getHostAddress()+"\n");
					}	
					
					else if(groupInformation[0].equals("GUFG")) {
						this.printStatusMsg("Get Users For Group "+groupInformation[1]+" Request from: "+packet.getAddress().getHostAddress()+"\n");
					}		
					
					else if(groupInformation[0].equals("JG")) {
						this.printStatusMsg("Get Join Group "+groupInformation[1]+" Request from: "+packet.getAddress().getHostAddress()+"\n");
					}		
					
					else 
						this.printStatusMsg("Audio Stream from: "+packet.getAddress().getHostAddress()+"\n");
					
				}
				
				ClientHandler clientHanlder = new ClientHandler(packet, this.mutex, this.groupData, this.serverSocket);
				clientHanlder.start();
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			this.numberOfBytesTransfered = this.numberOfBytesTransfered + packet.getLength();
					
		 }
		 
		 
	 }
	
	public static String getTime() {
		
	    Calendar cal = Calendar.getInstance();
	    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
	    
	    return sdf.format(cal.getTime());

	  }
	
	int getNumberOfBytesTransfered() {
		
		return this.numberOfBytesTransfered;
	}
	
	Map<String, String> getTrafficByGroup() {
		
		return this.trafficByGroup;
	}
	
	
	public void setupGUI() {	
		
		
		Font statusAreaFont = new Font(Font.DIALOG, Font.BOLD, 12);	
		this.setClosable(true);
		this.statusArea = new JTextArea ();		
		this.statusArea.setEditable(false);
		this.statusArea.setFont(statusAreaFont);
		this.statusArea.setForeground(Color.GREEN);				
		this.add(new JScrollPane(statusArea));		
		this.setSize(400, 400);
		this.setVisible(true);		
		
	}
	
	public void printStatusMsg(String msg) {
		
		this.statusArea.append(this.getTime()+"> "+msg);
	}
	
	public void send(byte[] packet, InetAddress remoteAdress, int remotePort) {	 
		 
		 
		 DatagramPacket datagramPacket = new DatagramPacket(new byte[1], 1, remoteAdress, remotePort);
		 datagramPacket.setData(packet);
	 }
	 
	
	 
	 DatagramPacket recv() {		 
		 
		 byte[] buffer = new byte[3000];
		 DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
		
			try {					
				this.serverSocket.receive(packet);	
				this.printStatusMsg("Getting packet from "+packet.getAddress().toString()+":"+packet.getPort());
				//this.send(packet.getData(), packet.getAddress(), packet.getPort());
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			return packet;
	}
	 
	
	 
	 
	 public List<String> getAllGroups() {
		 
		 return null;
	 }

		 
}
	 
	 
	
	 
	

